"""
文件上传API
处理文件上传相关的请求
"""

import os
import logging
from flask import request, jsonify, current_app
from werkzeug.utils import secure_filename
from . import api_bp
from ..services.file_service import FileService
from ..services.task_service import TaskService
from ..services.user_service import UserService
from ..utils.auth_utils import require_auth, get_current_user
from ..utils.validation_utils import ValidationUtils

logger = logging.getLogger(__name__)

@api_bp.route('/upload', methods=['POST'])
@require_auth
def upload_file():
    """
    上传文件接口
    
    Returns:
        JSON响应包含上传结果和任务信息
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        user_id = current_user['id']
        
        # 检查用户配额
        user_service = UserService(current_app)
        quota_result = user_service.check_quota(user_id)
        
        if not quota_result['success']:
            return jsonify({'error': quota_result['error']}), 400
        
        quota_info = quota_result['quota_info']
        if not quota_info['can_create_task']:
            return jsonify({'error': '已达到任务配额限制'}), 429
        
        # 检查文件
        if 'file' not in request.files:
            return jsonify({'error': '未选择文件'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'error': '未选择文件'}), 400
        
        # 获取转换参数
        output_format = request.form.get('output_format', 'pdf').lower()
        template_id = request.form.get('template_id')
        options = {}
        
        # 解析转换选项
        if request.form.get('page_size'):
            options['page_size'] = request.form.get('page_size')
        
        if request.form.get('margin'):
            options['margin'] = request.form.get('margin')
        
        if request.form.get('font_size'):
            options['font_size'] = request.form.get('font_size')
        
        if request.form.get('include_toc'):
            options['include_toc'] = request.form.get('include_toc').lower() == 'true'
        
        if request.form.get('custom_css'):
            options['custom_css'] = request.form.get('custom_css')
        
        # 验证输出格式
        allowed_formats = current_app.config.get('ALLOWED_OUTPUT_FORMATS', ['pdf', 'docx', 'html', 'epub'])
        if output_format not in allowed_formats:
            return jsonify({'error': f'不支持的输出格式: {output_format}'}), 400
        
        # 上传文件
        file_service = FileService(current_app)
        upload_result = file_service.upload_file(file, user_id)
        
        if not upload_result['success']:
            return jsonify({'error': upload_result['error']}), 400
        
        file_info = upload_result['file_info']
        
        # 创建转换任务
        task_service = TaskService(current_app)
        task_data = {
            'user_id': user_id,
            'filename': file_info['filename'],
            'original_filename': file_info['original_filename'],
            'file_path': file_info['file_path'],
            'file_size': file_info['file_size'],
            'file_hash': file_info['file_hash'],
            'output_format': output_format,
            'template_id': template_id,
            'options': options
        }
        
        task_result = task_service.create_task(task_data)
        
        if not task_result['success']:
            # 如果任务创建失败，删除已上传的文件
            file_service.delete_file(file_info['file_path'])
            return jsonify({'error': task_result['error']}), 500
        
        task_id = task_result['task_id']
        
        # 启动转换任务
        start_result = task_service.start_task(task_id)
        
        if not start_result['success']:
            return jsonify({'error': start_result['error']}), 500
        
        logger.info(f"文件上传成功: {user_id} - {file_info['filename']} - 任务ID: {task_id}")
        
        return jsonify({
            'success': True,
            'message': '文件上传成功，转换任务已开始',
            'task_id': task_id,
            'file_info': {
                'filename': file_info['filename'],
                'original_filename': file_info['original_filename'],
                'file_size': file_info['file_size'],
                'upload_time': file_info['upload_time']
            },
            'task_info': {
                'output_format': output_format,
                'template_id': template_id,
                'options': options,
                'estimated_duration': start_result.get('estimated_duration', 60)
            }
        }), 200
        
    except Exception as e:
        logger.error(f"文件上传失败: {str(e)}")
        return jsonify({'error': '文件上传失败，请稍后重试'}), 500

@api_bp.route('/upload/validate', methods=['POST'])
@require_auth
def validate_upload():
    """
    验证上传文件
    
    Returns:
        JSON响应包含验证结果
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        # 检查文件
        if 'file' not in request.files:
            return jsonify({'error': '未选择文件'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'error': '未选择文件'}), 400
        
        # 验证文件
        file_service = FileService(current_app)
        validation_result = file_service._validate_file(file)
        
        if not validation_result['valid']:
            return jsonify({
                'valid': False,
                'error': validation_result['error']
            }), 400
        
        # 获取文件信息
        file_info = {
            'filename': secure_filename(file.filename),
            'size': len(file.read()),
            'content_type': file.content_type
        }
        
        # 重置文件指针
        file.seek(0)
        
        return jsonify({
            'valid': True,
            'file_info': file_info,
            'message': '文件验证通过'
        }), 200
        
    except Exception as e:
        logger.error(f"文件验证失败: {str(e)}")
        return jsonify({'error': '文件验证失败'}), 500

@api_bp.route('/upload/chunk', methods=['POST'])
@require_auth
def upload_chunk():
    """
    分块上传文件
    
    Returns:
        JSON响应包含上传结果
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        user_id = current_user['id']
        
        # 获取分块信息
        chunk_number = int(request.form.get('chunk_number', 0))
        total_chunks = int(request.form.get('total_chunks', 1))
        file_id = request.form.get('file_id')
        filename = request.form.get('filename')
        
        if not all([file_id, filename]):
            return jsonify({'error': '缺少必要参数'}), 400
        
        # 检查文件块
        if 'chunk' not in request.files:
            return jsonify({'error': '未找到文件块'}), 400
        
        chunk = request.files['chunk']
        
        # 保存文件块
        file_service = FileService(current_app)
        chunk_result = file_service.save_chunk(
            chunk, user_id, file_id, filename, chunk_number, total_chunks
        )
        
        if not chunk_result['success']:
            return jsonify({'error': chunk_result['error']}), 400
        
        # 检查是否所有块都已上传
        if chunk_result.get('completed', False):
            # 合并文件块
            merge_result = file_service.merge_chunks(user_id, file_id, filename, total_chunks)
            
            if not merge_result['success']:
                return jsonify({'error': merge_result['error']}), 500
            
            return jsonify({
                'success': True,
                'completed': True,
                'file_info': merge_result['file_info'],
                'message': '文件上传完成'
            }), 200
        
        return jsonify({
            'success': True,
            'completed': False,
            'chunk_number': chunk_number,
            'message': f'文件块 {chunk_number + 1}/{total_chunks} 上传成功'
        }), 200
        
    except Exception as e:
        logger.error(f"分块上传失败: {str(e)}")
        return jsonify({'error': '分块上传失败'}), 500

@api_bp.route('/upload/status/<file_id>', methods=['GET'])
@require_auth
def get_upload_status(file_id):
    """
    获取上传状态
    
    Args:
        file_id: 文件ID
        
    Returns:
        JSON响应包含上传状态
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        user_id = current_user['id']
        
        file_service = FileService(current_app)
        status_result = file_service.get_upload_status(user_id, file_id)
        
        if not status_result['success']:
            return jsonify({'error': status_result['error']}), 404
        
        return jsonify({
            'success': True,
            'status': status_result['status']
        }), 200
        
    except Exception as e:
        logger.error(f"获取上传状态失败: {str(e)}")
        return jsonify({'error': '获取上传状态失败'}), 500

@api_bp.route('/upload/cancel/<file_id>', methods=['DELETE'])
@require_auth
def cancel_upload(file_id):
    """
    取消上传
    
    Args:
        file_id: 文件ID
        
    Returns:
        JSON响应包含取消结果
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        user_id = current_user['id']
        
        file_service = FileService(current_app)
        cancel_result = file_service.cancel_upload(user_id, file_id)
        
        if not cancel_result['success']:
            return jsonify({'error': cancel_result['error']}), 400
        
        return jsonify({
            'success': True,
            'message': '上传已取消'
        }), 200
        
    except Exception as e:
        logger.error(f"取消上传失败: {str(e)}")
        return jsonify({'error': '取消上传失败'}), 500

@api_bp.route('/upload/formats', methods=['GET'])
def get_supported_formats():
    """
    获取支持的输出格式
    
    Returns:
        JSON响应包含支持的格式列表
    """
    try:
        formats = current_app.config.get('ALLOWED_OUTPUT_FORMATS', ['pdf', 'docx', 'html', 'epub'])
        
        format_info = {
            'pdf': {
                'name': 'PDF',
                'description': 'Portable Document Format',
                'extension': '.pdf',
                'supports_images': True,
                'supports_tables': True
            },
            'docx': {
                'name': 'Word Document',
                'description': 'Microsoft Word Document',
                'extension': '.docx',
                'supports_images': True,
                'supports_tables': True
            },
            'html': {
                'name': 'HTML',
                'description': 'HyperText Markup Language',
                'extension': '.html',
                'supports_images': True,
                'supports_tables': True
            },
            'epub': {
                'name': 'EPUB',
                'description': 'Electronic Publication',
                'extension': '.epub',
                'supports_images': True,
                'supports_tables': True
            },
            'rtf': {
                'name': 'RTF',
                'description': 'Rich Text Format',
                'extension': '.rtf',
                'supports_images': False,
                'supports_tables': True
            },
            'odt': {
                'name': 'ODT',
                'description': 'OpenDocument Text',
                'extension': '.odt',
                'supports_images': True,
                'supports_tables': True
            }
        }
        
        supported_formats = []
        for format_key in formats:
            if format_key in format_info:
                supported_formats.append({
                    'key': format_key,
                    **format_info[format_key]
                })
        
        return jsonify({
            'success': True,
            'formats': supported_formats
        }), 200
        
    except Exception as e:
        logger.error(f"获取支持格式失败: {str(e)}")
        return jsonify({'error': '获取支持格式失败'}), 500

@api_bp.route('/upload/limits', methods=['GET'])
@require_auth
def get_upload_limits():
    """
    获取上传限制信息
    
    Returns:
        JSON响应包含上传限制
    """
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify({'error': '用户未认证'}), 401
        
        user_id = current_user['id']
        
        # 获取用户配额信息
        user_service = UserService(current_app)
        quota_result = user_service.check_quota(user_id)
        
        if not quota_result['success']:
            return jsonify({'error': quota_result['error']}), 400
        
        quota_info = quota_result['quota_info']
        
        # 获取系统限制
        max_file_size = current_app.config.get('MAX_CONTENT_LENGTH', 16 * 1024 * 1024)
        allowed_extensions = current_app.config.get('ALLOWED_EXTENSIONS', ['.md', '.markdown', '.txt'])
        
        return jsonify({
            'success': True,
            'limits': {
                'max_file_size': max_file_size,
                'max_file_size_mb': max_file_size // (1024 * 1024),
                'allowed_extensions': allowed_extensions,
                'user_quota': quota_info,
                'chunk_size': 1024 * 1024,  # 1MB chunks
                'max_chunks': 100
            }
        }), 200
        
    except Exception as e:
        logger.error(f"获取上传限制失败: {str(e)}")
        return jsonify({'error': '获取上传限制失败'}), 500